package cn.iocoder.yudao.module.contract.controller.admin.exportContract;

import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.module.contract.controller.admin.orderContract.vo.OrderContractSaveReqVO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.exportContract.ExportContractDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDetailsDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.orderContract.OrderContractDO;
import cn.iocoder.yudao.module.contract.dal.mysql.order.OrderDetailsMapper;
import cn.iocoder.yudao.module.contract.service.order.OrderService;
import cn.iocoder.yudao.module.contract.utils.FileDownloadUtil;
import cn.iocoder.yudao.module.contract.utils.StringUtils;
import cn.iocoder.yudao.module.contract.webservice.ContractWebService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Wrapper;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.contract.controller.admin.exportContract.vo.*;
import cn.iocoder.yudao.module.contract.dal.dataobject.exportContract.ExportContractDO;
import cn.iocoder.yudao.module.contract.service.exportContract.ExportContractService;

@Tag(name = "管理后台 - 出口合同")
@RestController
@RequestMapping("/contract/export-contract")
@Validated
public class ExportContractController {

    @Resource
    private ExportContractService exportContractService;
    @Resource
    private ContractWebService contractWebService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderDetailsMapper orderDetailsMapper;

    @PostMapping("/create")
    @Operation(summary = "创建出口合同")
    @PreAuthorize("@ss.hasPermission('contract:export-contract:create')")
    public CommonResult<Long> createExportContract(@Valid @RequestBody ExportContractSaveReqVO createReqVO) {
        return success(exportContractService.createExportContract(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新出口合同")
    @PreAuthorize("@ss.hasPermission('contract:export-contract:update')")
    public CommonResult<Boolean> updateExportContract(@Valid @RequestBody ExportContractSaveReqVO updateReqVO) {
        exportContractService.updateExportContract(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除出口合同")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('contract:export-contract:delete')")
    public CommonResult<Boolean> deleteExportContract(@RequestParam("id") Long id) {
        exportContractService.deleteExportContract(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得出口合同")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('contract:export-contract:query')")
    public CommonResult<ExportContractRespVO> getExportContract(@RequestParam("id") Long id) {
        ExportContractDO exportContract = exportContractService.getExportContract(id);
        return success(BeanUtils.toBean(exportContract, ExportContractRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得出口合同分页")
    @PreAuthorize("@ss.hasPermission('contract:export-contract:query')")
    public CommonResult<PageResult<ExportContractRespVO>> getExportContractPage(@Valid ExportContractPageReqVO pageReqVO) {
        PageResult<ExportContractDO> pageResult = exportContractService.getExportContractPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ExportContractRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出出口合同 Excel")
    @PreAuthorize("@ss.hasPermission('contract:export-contract:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportExportContractExcel(@Valid ExportContractPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ExportContractDO> list = exportContractService.getExportContractPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "出口合同.xls", "数据", ExportContractExportVO.class,
                        BeanUtils.toBean(list, ExportContractExportVO.class));
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download")
    public ResponseEntity<?> download(String ids) throws UnsupportedEncodingException {
        String[] id = ids.split(",");
        if (id.length == 1) {
            //单文件下载
            ExportContractDO exportContract = exportContractService.getById(id[0]);
            exportContract.setDownloadCount(exportContract.getDownloadCount() + 1);
            exportContractService.updateById(exportContract);
            //orderDO.getVbeln()+orderDO.getKname()+orderDO.getVkorg()+orderDO.getYwyt()
            String fileNmae = exportContract.getKname()+exportContract.getBstnk()+exportContract.getVkorg();
            return FileDownloadUtil.downloadFile(exportContract.getContractFileUrl(), URLEncoder.encode(fileNmae,"UTF-8") );
        } else if (id.length > 1) {
            //批量下载
            List<ExportContractDO> list = exportContractService.list(Wrappers.<ExportContractDO>lambdaQuery().in(ExportContractDO::getId, id));
            List<String> fileUrls = new ArrayList<>();
            List<String> fileNames = new ArrayList<>();
            for (ExportContractDO exportContract : list) {
                fileUrls.add(exportContract.getContractFileUrl());
                String fileNmae = exportContract.getKname()+exportContract.getBstnk()+exportContract.getVkorg()+("2".equals(exportContract.getType())?"佣金合同":"");
                fileNames.add(fileNmae);
//                fileNames.add(orderDO.getVbeln()+orderDO.getKname()+orderDO.getVkorg()+orderDO.getYwyt());
            }
            exportContractService.update(Wrappers.<ExportContractDO>update().setSql(" download_count = download_count + 1").in("id", id));
            return FileDownloadUtil.downloadZip(fileUrls, fileNames);
        } else {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "请选择要下载的合同");

        }
    }

    /**
     * 合同打印计数
     */
    @GetMapping("/prints")
    public CommonResult<?> prints(String ids) {
        String[] id = ids.split(",");
        if (id.length != 0) {
            exportContractService.update(Wrappers.<ExportContractDO>update().setSql(" print_count = print_count + 1").in("id", id));
            return success("操作成功");
        } else {
            return CommonResult.error(NOT_IMPLEMENTED);
        }
    }

    @PutMapping("/fileUpload")
    @Operation(summary = "合同上传")
    public CommonResult<Boolean> fileUpload(@Valid @RequestBody OrderContractSaveReqVO updateReqVO) {

        ExportContractDO updateObj = BeanUtils.toBean(updateReqVO, ExportContractDO.class);
        exportContractService.updateById(updateObj);
        ExportContractDO exportContract = exportContractService.getById(updateReqVO.getId());
////        exportContractService.fileUpload(updateReqVO);
////        exportContract.setFileIds(updateReqVO.getFileIds());
        if (StringUtils.isNotBlank(updateReqVO.getFileIds()) || StringUtils.isNotBlank(updateReqVO.getScanFileIds()) ) {
            updateObj.setStatus("4");
            List<OrderDO> orderList = orderService.list(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getContractNo,exportContract.getBstnk()) );
            for(OrderDO orderDO : orderList){
                //合同上传回收 4
                contractWebService.pushOrderStatus(orderDO.getVbeln(),exportContract);
                if(!"1".equals(exportContract.getIsPushRelease())){
                    break;
                }
            }
            exportContractService.updateById(updateObj);
        }
        return success(true);
    }

    @GetMapping("/pushRelease")
    @Operation(summary = "推送释放")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> pushRelease(@RequestParam("id") Long id) {
        ExportContractDO exportContract = exportContractService.getById(id);
        List<OrderDO> orderList = orderService.list(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getContractNo,exportContract.getBstnk()) );
        for(OrderDO orderDO : orderList){
            //重新推送
            contractWebService.pushOrderStatus(orderDO.getVbeln(),exportContract);
            if(!"1".equals(exportContract.getIsPushRelease())){
                exportContractService.updateById(exportContract);
                return error(exportContract.getAbnormalCause());
            }
        }
        exportContractService.updateById(exportContract);
        return success(true);

    }

    @GetMapping("/cancellation")
    @Operation(summary = "作废")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> cancellation(@RequestParam("id") Long id) {
        ExportContractDO exportContract = exportContractService.getById(id);
        List<ExportContractDO> list = exportContractService.list(Wrappers.<ExportContractDO>lambdaQuery().eq(ExportContractDO::getBstnk,exportContract.getBstnk()).ne(ExportContractDO::getStatus,"3"));
        for(ExportContractDO exportContractDo : list){
            exportContractDo.setStatus("3");
            exportContractDo.setContractHtml("");
            exportContractDo.setContractFileUrl("");
            exportContractService.updateById(exportContractDo);
        }
        exportContract = exportContractService.getById(id);
        List<OrderDO> orderList = orderService.list(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getContractNo,exportContract.getBstnk()) );
        for(OrderDO orderDO : orderList){
            //合同作废 3
            contractWebService.pushOrderStatus(orderDO.getVbeln(),exportContract);
            OrderDO order = new OrderDO();
            order.setId(orderDO.getId());
            order.setContractId("");
            order.setContractNo("");
            order.setStatus("0");
            orderService.updateById(order);
        }
        exportContractService.updateById(exportContract);
        return success(true);

    }

    @GetMapping("/generateContractFile")
    @Operation(summary = "合同生成")
    public CommonResult<Boolean> generateContractFile(String id) {
        ExportContractDO exportContract = exportContractService.getById(id);
        if (exportContract == null) {
            return error("合同不存在");
        }
        List<OrderDetailsDO> detailsList = orderDetailsMapper.selectList(Wrappers.<OrderDetailsDO>lambdaQuery().in(OrderDetailsDO::getVbeln,Arrays.asList(exportContract.getVbelns().split(","))).orderByAsc(OrderDetailsDO::getVbeln,OrderDetailsDO::getPosnr));

        exportContractService.generateContractFile(exportContract,detailsList);
        if("2".equals(exportContract.getStatus())){
            List<OrderDO> orderList = orderService.list(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getContractNo,exportContract.getBstnk()) );
            for(OrderDO orderDO : orderList){
                //合同重新生成 2
                contractWebService.pushOrderStatus(orderDO.getVbeln(),exportContract);
                if(!"1".equals(exportContract.getIsPushRelease())){
                    break;
                }
            }
        }
        exportContractService.updateById(exportContract);
        if (!"2".equals(exportContract.getStatus())) {
            return error(exportContract.getAbnormalCause());
        }
        return success(true);
    }
}